home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 09 - 1993 / 09.02 Feb 93 / Jörg's Folder / trap.compiler < prev   
Encoding:
Text File  |  1992-09-01  |  8.8 KB  |  494 lines  |  [TEXT/NISI]

  1. ONLY I/O
  2. ALSO ASSEMBLER
  3. ALSO MAC
  4. ALSO FORTH DEFINITIONS
  5.  
  6. \ Trapname Trap.opcode traptype selector stacksetup
  7.  
  8. \ IF traptype = ToolTrap
  9. \     stacksetup = ( w32 w16 w32 w32 … -- w32/16 )
  10.  
  11. \ IF traptype = OSTrap
  12. \     stacksetup = ( A0.W D0.W A1.W  -- xx.W )
  13. \                  ( A0.L D0.L A1.L  -- xx.L )
  14.  
  15. \ Examples
  16.  
  17. \ Open        A000 OSTrap ( A0.L -- D0.W )
  18. \ HOpen       A200 OSTrap ( A0.L -- D0.W )
  19. \ HOpen,ASYNC A600 OSTrap ( A0.L -- D0.W )
  20. \ Silly       A999 OSTrap REG( 1234 ) ( A0.L -- D0.W )
  21.  
  22. 1 CONSTANT trap.input
  23. 0 CONSTANT trap.output
  24. 1 CONSTANT OSTrap
  25. 2 CONSTANT ToolTrap
  26.  
  27. 60 USER FILEID
  28.  
  29. VARIABLE compile.state
  30. VARIABLE trapType
  31. VARIABLE input.parms
  32. VARIABLE trap.buffer 22 VALLOT
  33. VARIABLE name.buffer 28 VALLOT
  34.  
  35. CODE HashName16    ( @pstr -- hashvalue )
  36.     MOVE.L    (A6)+,A0
  37.     MOVEQ.L    #0,D2
  38.     MOVE.B    (A0)+,D2
  39.     MOVE.L    D2,D0
  40.     AND.B    #$1F,D2
  41.     BRA.S    @lptest
  42.  
  43. @loop
  44.     ROL.W    #7,D0
  45.     MOVE.B    (A0)+,D1
  46.     EOR.B    D1,D0
  47.  
  48. @lptest
  49.     DBRA    D2,@loop
  50.     MOVE.L    D0,-(A6)
  51.     RTS
  52. END-CODE
  53.  
  54. : --
  55.     trap.output compile.state ! 
  56.     ;
  57.  
  58. : w32
  59.     trapType @ ToolTrap =
  60.     IF
  61.         compile.state @ trap.input =
  62.         IF
  63.             1 input.parms +!
  64.             trap.buffer 4+ W@ 2* 1+
  65.             trap.buffer 4+ W!
  66.         ELSE
  67.             ( set the two high bits of byte4 )
  68.             input.parms @ $3F AND $40 OR
  69.             input.parms !
  70.         THEN
  71.     ELSE
  72.         CR ." Cannot mix OSTrap and ToolTrap Definitions." ABORT
  73.     THEN
  74.     ;
  75.  
  76. : w16
  77.     trapType @ ToolTrap =
  78.     IF
  79.         compile.state @ trap.input =
  80.         IF
  81.             1 input.parms +!
  82.             trap.buffer 4+ W@ 2*
  83.             trap.buffer 4+ W!
  84.         ELSE
  85.             ( set the two high bits of byte4 )
  86.             input.parms @ $3F AND $80 OR
  87.             input.parms !
  88.         THEN
  89.     ELSE
  90.         CR ." Cannot mix OSTrap and ToolTrap Definitions." ABORT
  91.     THEN
  92.     ;
  93.  
  94. : A1.W 
  95.     compile.state @ trap.input =
  96.     IF
  97.         trap.buffer 4+ W@ $80 OR $FFBF AND
  98.         trap.buffer 4+ W!
  99.         1 input.parms +!
  100.     ELSE
  101.         trap.buffer 4+ W@ $0002 OR $FFFE AND
  102.         trap.buffer 4+ W!
  103.         16 input.parms +!
  104.     THEN
  105.     ;
  106.  
  107. : A1.L
  108.     compile.state @ trap.input =
  109.     IF
  110.         trap.buffer 4+ W@ $C0 OR
  111.         trap.buffer 4+ W!
  112.         1 input.parms +!
  113.     ELSE
  114.         trap.buffer 4+ W@ $0003 OR
  115.         trap.buffer 4+ W!
  116.         16 input.parms +!
  117.     THEN
  118.     ;
  119.  
  120. : A0.W
  121.     compile.state @ trap.input =
  122.     IF
  123.         trap.buffer 4+ W@ $800 OR $FBFF AND
  124.         trap.buffer 4+ W!
  125.         1 input.parms +!
  126.     ELSE
  127.         trap.buffer 4+ W@ $0020 OR $FFEF AND
  128.         trap.buffer 4+ W!
  129.         16 input.parms +!
  130.     THEN
  131.     ;
  132.  
  133. : A0.L
  134.     compile.state @ trap.input =
  135.     IF
  136.         trap.buffer 4+ W@ $C00 OR
  137.         trap.buffer 4+ W!
  138.         1 input.parms +!
  139.     ELSE
  140.         trap.buffer 4+ W@ $0030 OR
  141.         trap.buffer 4+ W!
  142.         16 input.parms +!
  143.     THEN
  144.     ;
  145.  
  146. : D0.W
  147.     compile.state @ trap.input =
  148.     IF
  149.         trap.buffer 4+ W@ $200 OR $FEFF AND
  150.         trap.buffer 4+ W!
  151.         1 input.parms +!
  152.     ELSE
  153.         trap.buffer 4+ W@ $0008 OR $FFFB AND
  154.         trap.buffer 4+ W!
  155.         16 input.parms +!
  156.     THEN
  157.     ;
  158.  
  159. : D0.L
  160.     compile.state @ trap.input =
  161.     IF
  162.         trap.buffer 4+ W@ $300 OR
  163.         trap.buffer 4+ W!
  164.         1 input.parms +!
  165.     ELSE
  166.         trap.buffer 4+ W@ $000C OR
  167.         trap.buffer 4+ W!
  168.         16 input.parms +!
  169.     THEN
  170.     ;
  171.  
  172. : compile.selector
  173.     ( n -- )
  174.     ( The logic works like this:
  175.         set bit 15 of the trap word
  176.         IF the selector is to be put in D0
  177.             set bit 14 of the trap word
  178.             IF the selector is a longword
  179.                 set bit 13 of the trapword
  180.             ELSE the selector is a word
  181.                 clear bit 13 of the trapword
  182.             THEN
  183.         ELSE the selector is to be put on the stack
  184.             clear bit 14 of the trap word            
  185.             IF the selector is a longword
  186.                 set bit 13 of the trapword
  187.             ELSE
  188.                 CLEAR bit 13 of the trapword
  189.             THEN
  190.         THEN
  191.     )
  192.  
  193.     trap.buffer 6 + !
  194.     trap.buffer 10 + W@ $8000 OR
  195.     trap.buffer 10 + W!
  196.     ;
  197.  
  198. : is.white.space?
  199.     C@ DUP $20 = SWAP $09 = OR ;
  200.  
  201. : get.next.word
  202.     { | start.addr addr word.addr -- addr }
  203.     ( imitate WORD but remove white space )
  204.     
  205.     WORD -> word.addr 
  206.     word.addr 1+ -> addr
  207.     BEGIN
  208.         addr is.white.space?
  209.     WHILE
  210.         1 +> addr
  211.     REPEAT
  212.     
  213.     addr -> start.addr
  214.     1 +> addr
  215.     
  216.     BEGIN
  217.         addr is.white.space? NOT
  218.     WHILE
  219.         1 +> addr
  220.     REPEAT
  221.     
  222.     addr start.addr - word.addr C!
  223.     start.addr word.addr 1+ = NOT
  224.     IF
  225.         ( move the string )
  226.         start.addr word.addr 1+ word.addr C@
  227.         CMOVE
  228.     THEN
  229.     word.addr
  230.     ;
  231.     
  232. : REG(        ( word to compile a 16-bit selector into D0 )
  233.     ASCII ) get.next.word NUMBER?
  234.     0=
  235.     IF
  236.         CR
  237.         ." A trap routine selector must follow REG( "
  238.         ABORT
  239.     ELSE
  240.         ( -- selector )
  241.         ( set bit 14 of the Trap word )
  242.         trap.buffer 10 + W@ $4000 OR $DFFF AND
  243.         trap.buffer 10 + W!
  244.         compile.selector
  245.     THEN
  246.     ;
  247.  
  248. : LREG(        ( word to compile a longword->D0 selector )
  249.     ASCII ) get.next.word NUMBER?
  250.     0=
  251.     IF
  252.         CR
  253.         ." A trap routine selector must follow REG( "
  254.         ABORT
  255.     ELSE
  256.         ( -- selector )
  257.         ( set bit 14 and 13 of the Trap word )
  258.         trap.buffer 10 + W@ $6000 OR    
  259.         trap.buffer 10 + W!
  260.         compile.selector
  261.     THEN
  262.     ;
  263.  
  264. : STACK(        ( word to return the size of a defined record )
  265.     ASCII ) get.next.word NUMBER?
  266.     0=
  267.     IF
  268.         CR
  269.         ." A trap routine selector must follow STACK( " 
  270.         CR ABORT
  271.     ELSE
  272.         ( -- selector )
  273.         trap.buffer 10 + W@ $9FFF AND
  274.         trap.buffer 10 + W!
  275.         compile.selector
  276.     THEN
  277.     ;
  278.  
  279. : LSTACK(        ( word to return the size of a defined record )
  280.     ASCII ) get.next.word NUMBER?
  281.     0=
  282.     IF
  283.         CR
  284.         ." A trap routine selector must follow STACK( " 
  285.         CR ABORT
  286.     ELSE
  287.         ( -- selector )
  288.         trap.buffer 10 + W@ $BFFF AND $2000 OR
  289.         trap.buffer 10 + W!
  290.         compile.selector
  291.     THEN
  292.     ;
  293.  
  294. : SPECIAL
  295.     trap.buffer 10 + W@ $1000 OR
  296.     trap.buffer 10 + W!
  297.     ;
  298.  
  299. : compile.stack.spec
  300.     { | tword -- }
  301.     trap.input compile.state !
  302.     0 input.parms !
  303.     BEGIN
  304.         32 WORD -> tword
  305.         tword C@ 1 = tword 1+ C@ ASCII ) =  AND NOT
  306.     WHILE
  307.         tword FIND
  308.         0=
  309.         IF
  310.             CR ." Could not find stack spec word."  ABORT
  311.         ELSE
  312.             LINK>BODY EXECUTE
  313.         THEN
  314.     REPEAT
  315.     input.parms @ trap.buffer 3 + C!
  316.     ;
  317.  
  318. : compile.trap
  319.     { tword | save.base -- }
  320.     tword C@ name.buffer C!
  321.     tword C@ 31 > 
  322.     IF
  323.         31
  324.     ELSE
  325.         tword C@
  326.     THEN 0
  327.     DO
  328.         I 1+ tword + C@
  329.         DUP $60 >
  330.         IF
  331.             $DF AND
  332.         THEN
  333.         name.buffer I 1+ + C!
  334.     LOOP 
  335.  
  336.     name.buffer HashName16 trap.buffer W!
  337.     tword 1+ C@ trap.buffer 2+ C!
  338.     tword C@ trap.buffer 12 + C!
  339.     tword C@ 1- 13 >
  340.     IF
  341.         13
  342.     ELSE
  343.         tword C@ 1-
  344.     THEN
  345.     tword 2+ trap.buffer 13 + ROT CMOVE
  346.     ( now compile the opcode  )
  347.     32 WORD -> tword
  348.     tword BASE @ -> save.base
  349.     HEX NUMBER? save.base BASE !
  350.     0=
  351.     IF
  352.         CR ." The Trap Opcode must follow the trapname." ABORT
  353.     ELSE
  354.         $0FFF AND trap.buffer 10 + W!
  355.     THEN
  356.  
  357.     ( set trapType )
  358.     32 WORD FIND 0=
  359.     IF
  360.         CR ." Could not find the TrapType definition." ABORT
  361.     ELSE
  362.         LINK>BODY DUP ['] SPECIAL =
  363.         IF
  364.             EXECUTE
  365.             32 WORD FIND 0=
  366.             IF
  367.                 CR ." Could not find the TrapType definition." ABORT
  368.             THEN
  369.             LINK>BODY
  370.         THEN
  371.         EXECUTE    ( -- trapType )
  372.         CASE
  373.             OSTrap
  374.             OF 
  375.                 $7FFF trap.buffer 4+ W@ AND trap.buffer 4+ W!
  376.                 OSTrap trapType !
  377.             ENDOF
  378.             ToolTrap
  379.             OF
  380.                 $8000 trap.buffer 4+ W@ OR trap.buffer 4+ W!
  381.                 ToolTrap trapType !
  382.             ENDOF
  383.             ( else )
  384.             DROP CR ." Trap type definition (OS or Tool) is not valid." ABORT
  385.         ENDCASE
  386.     THEN
  387.  
  388.     ( now handle optional selector )
  389.     32 WORD -> tword
  390.     tword NUMBER?
  391.     IF
  392.         ( -- selector )
  393.         ( set bit 15 of the trap word )
  394.         trap.buffer 10 + W@ $8000 OR $9FFF AND
  395.         trap.buffer 10 + W!
  396.         ( store the selector )
  397.         trap.buffer 6 + !
  398.         BEGIN 0 WORD 1+ C@ ASCII ( = UNTIL
  399.     ELSE
  400.         DROP ( the invalid number )
  401.         ( it is either REG, STACK, or a open-paren )
  402.         tword C@ 1 = tword 1+ C@ ASCII ( = AND
  403.         IF
  404.             -1 trap.buffer 6 + !
  405.         ELSE
  406.             tword FIND
  407.             0=
  408.             IF
  409.                 CR ." Could not find the Trap selector word "
  410.                 tword COUNT TYPE ABORT
  411.             ELSE
  412.                 LINK>BODY EXECUTE
  413.                 ( now look for an open-paren to start the stack spec )
  414.                 BEGIN 0 WORD 1+ C@ ASCII ( = UNTIL
  415.             THEN
  416.         THEN
  417.     THEN
  418.     compile.stack.spec
  419.     trapType @ ToolTrap =
  420.     IF 
  421.         trap.buffer 4+ W@ $8000 OR trap.buffer 4+ W!
  422.     THEN
  423.     ;    
  424.  
  425. : save.TrapData
  426.     { thandle | file.str refnum old.handle -- }
  427.     " my.Trap.Data" -> file.str
  428.     file.str CALL OpenResFile -> refnum
  429.     refnum 0> NOT
  430.     IF
  431.         file.str CALL CreateResFile
  432.         file.str CALL OpenResFile -> refnum    
  433.     THEN
  434.     refnum 0>
  435.     IF
  436.         0 CALL SetResLoad
  437.         ASCII TEXT 2 CALL GetResource ( -- handle )
  438.         -> old.handle
  439.         old.handle 0= NOT
  440.         IF
  441.             old.handle CALL RmveResource
  442.             old.handle CALL DisposHandle DROP
  443.             refnum CALL UpdateResFile
  444.         THEN
  445.         1 CALL SetResLoad
  446.         thandle ASCII TEXT 2 " TrapData" CALL AddResource
  447.         refnum CALL UpdateResFile
  448.         refnum CALL CloseResFile
  449.     ELSE
  450.         CR ." Could not create the resource file " file.str COUNT TYPE ABORT
  451.     THEN
  452.     ;
  453.  
  454. : compile.traplist
  455.     { | tword thandle toffset saved.BLK saved.>IN -- }
  456.     4 CALL NewHandle 0=
  457.     IF
  458.         -> thandle
  459.         STANDARD-GETFILE
  460.         0= NOT
  461.         IF
  462.             BLK @ -> saved.BLK -1 BLK !
  463.             >IN @ -> saved.>IN 0 >IN !
  464.             
  465.             0 -> toffset
  466.             BEGIN
  467.                 32 WORD -> tword
  468.                 tword C@ 0= NOT
  469.             WHILE
  470.                 \ CR ." Compiling trap " tword COUNT TYPE
  471.                 trap.buffer 12 0 FILL
  472.                 trap.buffer 12 + 14 32 FILL
  473.                 thandle CALL GetHandleSize 26 +
  474.                 thandle SWAP CALL SetHandleSize 0= NOT
  475.                 IF
  476.                     CR ." Memory Error while expanding trap description buffer." ABORT
  477.                 THEN
  478.                 tword compile.trap
  479.                 ( at this point the trap should be compiled in trap.buffer )
  480.                 trap.buffer thandle @ toffset + 26 CMOVE
  481.                 26 +> toffset
  482.             REPEAT
  483.             saved.BLK BLK !
  484.             saved.>IN >IN !
  485.             FILEID W@ CLOSEFILE
  486.  
  487.             $25252525 thandle @ toffset + ! 
  488.             thandle save.TrapData
  489.             thandle CALL DisposHandle DROP
  490.         THEN
  491.     ELSE
  492.         CR ." Memory problems allocating handle." ABORT
  493.     THEN
  494.     ;